﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using WaitLess.Business.Data.Foursquare.Interfaces;
using WaitLess.Business.Data.Model.Foursquare.CheckinRequest;
using WaitLess.Business.Data.Model.Foursquare.HereNowResponse;
using WaitLess.Business.Data.Model.Foursquare.VenuesResponse;
using WaitLess.Business.Data.Web.Interfaces;

namespace WaitLess.Business.Data.Foursquare
{
    public class FoursquareContext : IFoursquareContext
    {
        private readonly IWebRequestor _webRequestor;

        public FoursquareContext(IWebRequestor webRequestor)
        {
            if (webRequestor == null) throw new ArgumentNullException("webRequestor");

            _webRequestor = webRequestor;
        }

        public void Venues(string query, Action<VenuesResponse> receiveResult)
        {
            if (string.IsNullOrWhiteSpace(query)) throw new ArgumentNullException("query");
            if (receiveResult == null) throw new ArgumentNullException("receiveResult");

            var uri = ApiUriBuilder.VenuesV2Url()
                .WithVersion(Settings.FoursquareApiVersion)
                .WithClientId(Settings.FoursquareClientId)
                .WithClientSecret(Settings.FoursquareClientSecret)
                .WithNear("Antwerp,Belgium")
                .WithIntent("checkin")
                .WithQuery(query);

            _webRequestor.Download(uri.ToString(), response => GetResult(response, receiveResult));
        }

        public void HereNow(string venueId, string accessToken, Action<HereNowResponse> receiveResult)
        {
            if (string.IsNullOrWhiteSpace(venueId)) throw new ArgumentNullException("venueId");
            if (string.IsNullOrWhiteSpace(accessToken)) throw new ArgumentNullException("accessToken");
            if (receiveResult == null) throw new ArgumentNullException("receiveResult");

            var secondsSinceEpoch = ((int)((DateTime.UtcNow - new DateTime(1970, 1, 1))).TotalSeconds).ToString();

            var uri = ApiUriBuilder.HereNowV2Url(venueId)
                .WithVersion(Settings.FoursquareApiVersion)
                .WithAccessToken(accessToken)
                .WithAfterTimestamp(secondsSinceEpoch);

            _webRequestor.Download(uri.ToString(), response => GetResult(response, receiveResult));
        }

        public void CheckIn(Request request, Action completedCallback)
        {
            if (request == null) throw new ArgumentNullException("request");
            if (string.IsNullOrWhiteSpace(request.AccessToken)) throw new ArgumentException("request.AccessToken", "request");
            if (string.IsNullOrWhiteSpace(request.VenueId)) throw new ArgumentException("request.VenueId", "request");
            if (string.IsNullOrWhiteSpace(request.Latitude)) throw new ArgumentException("request.Latitude", "request");
            if (string.IsNullOrWhiteSpace(request.Longitude)) throw new ArgumentException("request.Longitude", "request");
            if (completedCallback == null) throw new ArgumentNullException("completedCallback");

            var uri = ApiUriBuilder.AddCheckInUrl()
                .WithVersion(Settings.FoursquareApiVersion)
                .WithAccessToken(request.AccessToken);

            var latitudeLongitude = string.Format("{0},{1}", request.Longitude, request.Latitude);
            var parameters = new Dictionary<string, string> { { "venueId", request.VenueId }, { "ll", latitudeLongitude } };

            _webRequestor.Post(uri.ToString(), parameters, response => completedCallback());
        }

        private void GetResult(string response, Action<VenuesResponse> receiveResult)
        {
            var venues = JsonConvert.DeserializeObject<VenuesResponse>(response);

            receiveResult(venues);
        }

        private void GetResult(string response, Action<HereNowResponse> receiveResult)
        {
            var hereNow = JsonConvert.DeserializeObject<HereNowResponse>(response);

            receiveResult(hereNow);
        }
    }
}